package com.study.controller;

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author huang
 * @date 2019/2/27 15:56
 **/
@ServerEndpoint("/websocket/{username}")
@Component
public class WebSocketServer {
    private static Integer onLineCount = 0;
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
    private Session session;

    /**
     * 新建连接触发
     *
     * @param session  当前会话
     * @param username 获取访问地址参数，用户名
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "username") String username) {
        this.session = session;
        // 当前连接加入 set
        webSocketSet.add(this);
        // 连接数量加 1
        addOnlineCount();
        // 响应消息给当前连接
        sendMessage("连接成功");
        // 群发消息
        for (WebSocketServer webSocketServer : webSocketSet) {
            webSocketServer.sendMessage(username + " 加入聊天室, 当前人数：" + getOnlineCount());
        }

    }

    /**
     * 连接关闭触发
     */
    @OnClose
    public void onClose() {
        // 移除当前连接
        webSocketSet.remove(this);
        // 连接数量减 1
        subOnlineCount();
    }

    /**
     * 收到客户端消息触发
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        // 分发到各个 socket
        for (WebSocketServer webSocketServer : webSocketSet) {
            webSocketServer.sendMessage(message);
        }
    }

    /**
     * 异常
     */
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 推送消息给当前会话
     */
    private void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 群发自定义消息
     */
    static void doSend(String message) {
        for (WebSocketServer webSocketServer : webSocketSet) {
            webSocketServer.sendMessage(message);
        }
    }

    private static synchronized int getOnlineCount() {
        return onLineCount;
    }

    private static synchronized void addOnlineCount() {
        WebSocketServer.onLineCount++;
    }

    private static synchronized void subOnlineCount() {
        WebSocketServer.onLineCount--;
    }
}
